#include <limits>
#include <iostream>
using std::cout;
using std::ostream;
using std::istream;
using std::endl;

class Complex
{
public:
    Complex(double dreal = 0, double dimage = 0)
    : _dreal(dreal)
    , _dimage(dimage)
    {   cout << "Complex(double,double)" << endl;   }

    friend class Point;
    friend ostream & operator<<(ostream &os, const Complex & rhs);
private:
    double _dreal;
    double _dimage;
};

ostream & operator<<(ostream &os, const Complex & rhs)
{
    os << rhs._dreal;
    if(rhs._dimage > 0)
        os << " + " << rhs._dimage << "i";
    else if(rhs._dimage < 0)
        os <<  " - " << (-1) * rhs._dimage << "i";
    return os;
}

class Point
{
public:
    Point() = default;//默认构造函数

    Point(int ix, int iy = 0)
    : _ix(ix)
    , _iy(iy)
    {   cout << "Point(int,int)" << endl;   }

    //explicit
    Point(const Complex & rhs)
    : _ix(rhs._dreal)
    , _iy(rhs._dimage)
    {   cout << "Point(const Complex &)" << endl;   }

    void print() const
    {
        cout << "(" << _ix
             << "," << _iy
             << ")";
    }

    friend ostream & operator<<(ostream & os, const Point & rhs);
    friend istream & operator>>(istream & os, Point & rhs);

private:
    int _ix = 0;
    int _iy = 0;
};

ostream & operator<<(ostream & os, const Point & rhs)
{
     os << "(" << rhs._ix
          << "," << rhs._iy
          << ")";
     return os;
}

void readInteger(istream & is, int & x)
{
    cout << "pls input a valid integer:" << endl;
    while(is >> x, !is.eof()) {
        if(is.bad()) {
            cout << "istream has broken" << endl;
            return;
        } else if(is.fail()) {
            is.clear();
            is.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
            cout << "pls input a valid integer:" << endl;
        } else {
            return;
        }
    }
}

istream & operator>>(istream &is, Point & rhs)
{   //对于输入流来说，需要考虑每一次使用之后，流是否还有效
    readInteger(is, rhs._ix);
    readInteger(is, rhs._iy);
    return is;
}

void test0()
{
    //隐式转换： 
    //1.编译器先将1转换成Point(1, 0)对象
    //2.再将Point(1,0)对象复制构造新对象pt
    Point pt = 1;
    cout << "pt:" << pt << endl;

    Complex c1(1.1, 2.2);
    cout << "c1:" << c1 << endl;
    Point pt2 = c1;
    cout << "pt2:" << pt2 << endl;
}


int main()
{
    test0();
    return 0;
}

